package com.dx.mes.service.tool.service;
import static com.dx.mes.common.bean.def.GenericDef.ACTION_FLG_ADD;
import static com.dx.mes.common.bean.def.GenericDef.ACTION_FLG_DELETE;
import static com.dx.mes.common.bean.def.GenericDef.ACTION_FLG_QUERY;
import static com.dx.mes.common.bean.def.GenericDef.E_MBPREPMAG_BODY_ITEM_EXIST;
import static com.dx.mes.common.bean.def.GenericDef.E_MBPREPMAG_BODY_VALUE_CHECK_NG;
import static com.dx.mes.common.bean.def.GenericDef.E_MBPREPMAG_INVALID_INPUT;
import static com.dx.mes.common.bean.def.GenericDef.RETURN_CODE_OK;
import static com.dx.mes.common.bean.def.GenericDef.RETURN_CODE_SET_ERROR;
import static com.dx.mes.common.bean.def.GenericDef.RETURN_CODE_UNKNOWN;
import static com.dx.mes.common.bean.def.GenericDef.RETURN_MESG_OK;
import static com.dx.mes.common.bean.def.GenericDef.TRX_OUT;
import static com.dx.mes.common.bean.def.GenericDef.T_MBPREPMAG;
import static com.dx.mes.common.bean.def.GenericDef._NORMAL;
import static com.dx.mes.common.bean.def.GenericDef._YES;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dx.common.table.ppt.Bis_recipe;
import com.dx.common.table.ppt.Bis_recipe_body;
import com.dx.common.table.ppt.Bis_recipe_bodyId;
import com.dx.common.table.ppt.Ret_recipe;
import com.dx.common.table.ppt.Ret_recipe_body;
import com.dx.common.table.ppt.Ret_recipe_bodyId;
import com.dx.mes.common.dao.IBisRecipeBodyDao;
import com.dx.mes.common.dao.IBisRecipeDao;
import com.dx.mes.common.dao.IRetRecipeBodyDao;
import com.dx.mes.common.dao.IRetRecipeDao;
import com.dx.mes.common.transcoder.util.AppContext;
import com.dx.mes.common.transcoder.util.GUIDGenerator;
import com.dx.mes.common.transcoder.util.JacksonUtil;
import com.dx.mes.common.transcoder.util.LogUtils;
import com.dx.mes.common.transcoder.util.Util;
import com.dx.mes.facade.tool.service.IMbprepmagService;
import com.dx.mes.facade.tool.tx.Mbprepmag.MbprepmagI;
import com.dx.mes.facade.tool.tx.Mbprepmag.MbprepmagIA;
import com.dx.mes.facade.tool.tx.Mbprepmag.MbprepmagO;
import com.dx.mes.facade.tool.tx.Mbprepmag.MbprepmagOA;

/**
 * Created by ADMIN on 2017/12/4.
 */
@Service("mbprepmagService")
public class MbprepmagService implements IMbprepmagService {
    private static final String TX_NAME = T_MBPREPMAG;
    private LogUtils logUtils;
    @Autowired
    private IBisRecipeDao bisRecipeDao;
    @Autowired
    private IBisRecipeBodyDao bisRecipeBodyDao;
    @Autowired
    private IRetRecipeDao retRecipeDao;
    @Autowired
    private IRetRecipeBodyDao retRecipeBodyDao;

    @Override
    public String subMainProc(String evt_no, String strInMsg) {
        AppContext.clear();
        AppContext.setCurrServiceName(MbprepmagService.class.getSimpleName());
        AppContext.setCurrEventNumber(evt_no);
        logUtils = new LogUtils(MbprepmagService.class);
        logUtils.info("[InTrx:" + strInMsg + "]");
        Session session = bisRecipeDao.getCrSession();
        long rtnCode = _NORMAL;
        String outMsg = null;

        MbprepmagI inTrx = new MbprepmagI();
        MbprepmagO outTrx = new MbprepmagO();
        outTrx.setTrx_id(TX_NAME);
        outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
        outTrx.setType_id(TRX_OUT);
        try {
            inTrx = JacksonUtil.fromJson(strInMsg, MbprepmagI.class);

            rtnCode = subMainProc2(inTrx, outTrx);
            if (rtnCode != _NORMAL) {
                TransactionAspectSupport.currentTransactionStatus()
                        .setRollbackOnly();
                outTrx.setRtn_code(String.valueOf(rtnCode));
            } else {
                outTrx.setRtn_code(String.valueOf(RETURN_CODE_OK));
                outTrx.setRtn_mesg(RETURN_MESG_OK);
                session.flush();
            }
        } catch (Exception ex) {
            TransactionAspectSupport.currentTransactionStatus()
                    .setRollbackOnly();
            outTrx.setRtn_mesg(ex.toString());
            outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
            logUtils.error(Util.stackTraceToString(ex));
        } finally {
            outMsg = JacksonUtil.toJSONStr(outTrx);
            logUtils.info("[OutTrx:" + outMsg + "]");
        }
        return outMsg;
    }

    private long subMainProc2(MbprepmagI inTrx, MbprepmagO outTrx) {
        long lRc = _NORMAL;
        char actionType = inTrx.getAction_flg().toCharArray()[0];
        switch (actionType) {
            case ACTION_FLG_ADD: {
                lRc = addRecipeInfo(inTrx, outTrx);
                if (lRc != _NORMAL) {
                    return lRc;
                }
                break;
            }
            case ACTION_FLG_QUERY: {
                lRc = queryRecipeInfo(inTrx, outTrx);
                if (lRc != _NORMAL) {
                    return lRc;
                }
                break;
            }
            case ACTION_FLG_DELETE: {
                lRc = deleteRecipeInfo(inTrx, outTrx);
                if (lRc != _NORMAL) {
                    return lRc;
                }
                break;
            }
            case 'C':
            	lRc = checkRecipeInfo(inTrx, outTrx);
                if (lRc != _NORMAL) {
                    return lRc;
                }
            	break;
            default: {
                outTrx.setRtn_mesg("Invalide type input: [" + actionType + "]");
                return E_MBPREPMAG_INVALID_INPUT;
            }
        }
        return lRc;
    }

    private long addRecipeInfo(MbprepmagI inTrx, MbprepmagO outTrx) {
        long lRc = _NORMAL;
        String recipebodyid = GUIDGenerator.javaGUID();
        Timestamp gEvtTimestamp = Util.getCurrentTimestamp();
        MbprepmagIA iary = inTrx.getIary().get(0);
        List<Bis_recipe_body> bis_recipe_body_list = new ArrayList<Bis_recipe_body>();
        String hql_bis_recipe = "FROM Bis_recipe WHERE tool_id_fk ='" + iary.getTool_id_fk() 
        	+ "' and recipe_id ='" + iary.getRecipe_id() + "'";
        List<Bis_recipe> bis_recipe_list = bisRecipeDao.find(hql_bis_recipe);
        if(bis_recipe_list.isEmpty()){//未找到设备、recipe no的设定记录
            Bis_recipe bis_recipe = new Bis_recipe();
            bis_recipe.setEvt_seq_id(GUIDGenerator.javaGUID());
            bis_recipe.setRecipe_body_id_fk(recipebodyid);
            bis_recipe.setTool_id_fk(iary.getTool_id_fk());
            bis_recipe.setRecipe_id(iary.getRecipe_id());
            bis_recipe.setRecipe_ver("00000");
            bis_recipe.setEvt_usr(inTrx.getEvt_usr());
            bis_recipe.setEvt_timestamp(gEvtTimestamp);
            bisRecipeDao.save(bis_recipe);
        }else{
        	Bis_recipe bis_recipe = bis_recipe_list.get(0);
            recipebodyid = bis_recipe.getRecipe_body_id_fk();
        }
        
        //获取Recipe body设定的最大body_seq_id，从这个body_seq_id依次往后
        int body_seq_id = 1;
        String hql = "FROM Bis_recipe_body WHERE 1=1 and recipe_body_id='" + recipebodyid + "' order by body_seq_id desc";
        List<Bis_recipe_body> bis_recipe_bodyList = bisRecipeBodyDao.find(hql);
        if(bis_recipe_bodyList.isEmpty()){
        	body_seq_id = 1;
        }else{
        	body_seq_id = bis_recipe_bodyList.get(0).getId().getBody_seq_id() + 1;
        }
        
        for (int i = 0; i < inTrx.getIary().size(); i++,body_seq_id++) {
        	//检查设备、recipe no、body_item是否设定
            String hql2 = "FROM Bis_recipe_body WHERE 1=1 and recipe_body_id='" + recipebodyid 
            		+ "' and body_item='" + inTrx.getIary().get(i).getBody_item() + "'";
            List<Bis_recipe_body> bis_recipe_bodyList2 = bisRecipeBodyDao.find(hql2);
            if(bis_recipe_bodyList2.size()>0){
            	outTrx.setRtn_mesg("Body Name[" + inTrx.getIary().get(i).getBody_item() + "]已设定，请勿重复设定");
            	return E_MBPREPMAG_BODY_ITEM_EXIST;
            }
            Bis_recipe_bodyId bis_recipe_bodyId = new Bis_recipe_bodyId();
            bis_recipe_bodyId.setRecipe_body_id(recipebodyid);
            bis_recipe_bodyId.setBody_seq_id(body_seq_id);
            Bis_recipe_body bis_recipe_body = new Bis_recipe_body();
            bis_recipe_body.setId(bis_recipe_bodyId);
            bis_recipe_body.setTool_id_fk(iary.getTool_id_fk());
            bis_recipe_body.setBody_item(inTrx.getIary().get(i).getBody_item());
            bis_recipe_body.setBody_dsc(inTrx.getIary().get(i).getBody_dsc());
            bis_recipe_body.setBody_value_min(inTrx.getIary().get(i).getBody_value_min());
            bis_recipe_body.setBody_value_max(inTrx.getIary().get(i).getBody_value_max());
            bis_recipe_body.setBody_note(inTrx.getIary().get(i).getBody_note());
            bis_recipe_body.setEvt_usr(inTrx.getEvt_usr());
            bis_recipe_body.setEvt_timestamp(gEvtTimestamp);
            bis_recipe_body_list.add(bis_recipe_body);
        }
        bisRecipeBodyDao.saveOrUpdateAll(bis_recipe_body_list);
        return lRc;
    }
    
    private long queryRecipeInfo(MbprepmagI inTrx, MbprepmagO outTrx) {
        long lRc = _NORMAL;
        List<MbprepmagOA> oaryList = new ArrayList<MbprepmagOA>();
        MbprepmagIA iary = inTrx.getIary().get(0);
        String hql = "FROM Bis_recipe WHERE 1=1";
        if (!Util.isSpaceCheck(iary.getTool_id_fk())) {
            hql = hql + " and tool_id_fk ='" + iary.getTool_id_fk() + "'";
        }
        if (!Util.isSpaceCheck(iary.getRecipe_id())) {
            hql = hql + " and recipe_id ='" + iary.getRecipe_id() + "'";
        }
        List<Bis_recipe> bis_recipe_list = bisRecipeDao.find(hql);
        if(bis_recipe_list.size()>0){
            Bis_recipe bis_recipe = bis_recipe_list.get(0);
            String recipebodyid = bis_recipe.getRecipe_body_id_fk();
            String hql1 = "FROM Bis_recipe_body WHERE 1=1 and recipe_body_id='" + recipebodyid + "'";
            List<Bis_recipe_body> bis_recipe_bodyList = bisRecipeBodyDao.find(hql1);
            for(Bis_recipe_body bis_recipe_body:bis_recipe_bodyList){
                MbprepmagOA oary=new MbprepmagOA();
                oary.setTool_id_fk(bis_recipe_body.getTool_id_fk());
                oary.setBody_value_min(bis_recipe_body.getBody_value_min());
                oary.setBody_value_max(bis_recipe_body.getBody_value_max());
                oary.setBody_note(bis_recipe_body.getBody_note());
                oary.setBody_item(bis_recipe_body.getBody_item());
                oary.setBody_dsc(bis_recipe_body.getBody_dsc());
                oary.setRecipe_id(bis_recipe.getRecipe_id());
                oary.setBody_seq_id(String.valueOf(bis_recipe_body.getId().getBody_seq_id()));
                oary.setRecipe_body_id(bis_recipe_body.getId().getRecipe_body_id());
                oaryList.add(oary);
            }
            outTrx.setOaryA(oaryList);
        }
        return lRc;
    }
    
    private long deleteRecipeInfo(MbprepmagI inTrx, MbprepmagO outTrx) {
        long lRc = _NORMAL;
        List<MbprepmagIA> iaryList  = inTrx.getIary();
        List<Bis_recipe_body>  list = new ArrayList<>();
        for (MbprepmagIA mbprepmagIA :iaryList){
            Bis_recipe_bodyId id = new Bis_recipe_bodyId();
            id.setBody_seq_id(Integer.valueOf(mbprepmagIA.getBody_seq_id()));
            id.setRecipe_body_id(mbprepmagIA.getRecipe_body_id());
            Bis_recipe_body bis_recipe_body = bisRecipeBodyDao.get(id);
            if(bis_recipe_body!=null){
                list.add(bis_recipe_body);
            }
        }
        bisRecipeBodyDao.deleteAll(list);
        return lRc;
    }

    private long checkRecipeInfo(MbprepmagI inTrx, MbprepmagO outTrx) {
        long lRc = _NORMAL;
        String recipebodyid = GUIDGenerator.javaGUID();
        Timestamp gEvtTimestamp = Util.getCurrentTimestamp();
        List<Bis_recipe_body> bis_recipe_bodyList = new ArrayList<Bis_recipe_body>();
        List<Ret_recipe_body> ret_recipe_body_list = new ArrayList<Ret_recipe_body>();
        //保存Ret_recipe信息
    	Ret_recipe ret_recipe = new Ret_recipe();
    	ret_recipe.setEvt_seq_id(GUIDGenerator.javaGUID());
        ret_recipe.setTool_id_fk(inTrx.getTool_id());
        ret_recipe.setRecipe_id(inTrx.getRecipe_id());
        ret_recipe.setRecipe_ver("00000");
        ret_recipe.setRecipe_body_id_fk(recipebodyid);
        ret_recipe.setEvt_usr(inTrx.getEvt_usr());
        ret_recipe.setEvt_timestamp(gEvtTimestamp);
        retRecipeDao.save(ret_recipe);
        
        //保存设备上报的Recipe body值，获取BIS_RECIPE设定，比较范围
        String hql_bis_recipe = "FROM Bis_recipe WHERE tool_id_fk='" + inTrx.getTool_id()
        	+ "' AND recipe_id='" + inTrx.getRecipe_id() + "'";
        List<Bis_recipe> bis_recipe_list = bisRecipeDao.find(hql_bis_recipe);
        if(!bis_recipe_list.isEmpty()){
        	 Bis_recipe bis_recipe = bis_recipe_list.get(0);
             String hql_bis_recipe_body = "FROM Bis_recipe_body WHERE 1=1 and recipe_body_id='" + bis_recipe.getRecipe_body_id_fk() + "'";
             bis_recipe_bodyList = bisRecipeBodyDao.find(hql_bis_recipe_body);
        }
        
     	for(int i=0; i<inTrx.getIary().size(); i++){
    		Ret_recipe_body ret_recipe_body = new Ret_recipe_body();
    		Ret_recipe_bodyId ret_recipe_bodyId = new Ret_recipe_bodyId();
     		for(Bis_recipe_body bis_recipe_body:bis_recipe_bodyList){
     			if(bis_recipe_body.getBody_item().equals(inTrx.getIary().get(i).getBody_item())){
     				if(Double.valueOf(bis_recipe_body.getBody_value_max()) < Double.valueOf(inTrx.getIary().get(i).getBody_value()) ||
         					Double.valueOf(bis_recipe_body.getBody_value_min()) > Double.valueOf(inTrx.getIary().get(i).getBody_value())){
     	            	outTrx.setRtn_mesg("Body Name[" + inTrx.getIary().get(i).getBody_item() + "] Value Check NG");
     	            	return E_MBPREPMAG_BODY_VALUE_CHECK_NG;
     				}else{
     					break;
     				}
     			}
     		}
    		ret_recipe_bodyId.setRecipe_body_id(recipebodyid);
    		ret_recipe_bodyId.setBody_seq_id(i+1);
    		ret_recipe_body.setId(ret_recipe_bodyId);
    		ret_recipe_body.setTool_id_fk(inTrx.getTool_id());
    		ret_recipe_body.setBody_item(inTrx.getIary().get(i).getBody_item());
    		ret_recipe_body.setBody_value(inTrx.getIary().get(i).getBody_value());
    		ret_recipe_body.setValue_check_flg(_YES);
    		ret_recipe_body.setEvt_usr(inTrx.getEvt_usr());
    		ret_recipe_body.setEvt_timestamp(gEvtTimestamp);
    		ret_recipe_body_list.add(ret_recipe_body);
    	}
        
     	if(ret_recipe_body_list.size() > 0){
     		retRecipeBodyDao.saveOrUpdateAll(ret_recipe_body_list);
     	}
        return lRc;
    }
    
}